"""Captcha (Completely Automated Public Turing test to tell Computers and
Humans Apart) module for django

Author: Martin Winkler, June 2007
License: BSD
"""

from PIL import Image
from django.conf import settings
from django.utils.translation import gettext
from django.utils.datastructures import MultiValueDict
from django.contrib.captcha import captchasettings, errormsg
from django.contrib.captcha.imagecaptcha import Field, CaptchaWidget
from django.newforms import ValidationError
from django.http import HttpResponse

from base64 import b64encode, b64decode
from cPickle import dumps, loads
from pyDes import des


DYNFIELDS = ('solution', 'fgcolor', 'bgcolor', 'captchaconf_dir', 'minmaxvpos',
    'minmaxrotations', 'minmaxheight', 'minmaxkerning', 'num_lines',
    'line_width', 'imagesize', 'iterations', 'timestamp')
class DynCaptchaWidget(CaptchaWidget):
    """generate a captcha image and display the image along with
    a hidden field and a input field"""

    def __init__(self, options=None, *args, **kwargs):
        super(DynCaptchaWidget, self).__init__(options=options, *args, **kwargs)

    def encrypt_data(self):
        result = []
        for f in DYNFIELDS:
            result.append(self.csettings[f])

        k = des(settings.SECRET_KEY[-8:])
        return b64encode(k.encrypt(dumps(result), pad='='), altchars='._,')


    def render(self, name, value, attrs=None):
        imagename = self.encrypt_data()
        return u'''<input type="hidden" name="%(name)s" value="captcha.%(imagename)s"
/><img src="%(dyncaptchabase_url)s/%(imagename)s/" alt="" /><br
/><input type="text" name="%(name)s" id="id_%(name)s" />''' % {'name':name,
        'dyncaptchabase_url': self.csettings['dyncaptchabase_url'],
        'imagename': imagename }



class DynCaptchaField(Field):

    def __init__(self, required=True, label=None, help_text=None,
            options=None, *args, **kwargs):
        super(DynCaptchaField, self).__init__(required=required,
            widget=DynCaptchaWidget(options=options),
            label=label, help_text=help_text, *args, **kwargs
            )
    def clean(self, value):
        if not isinstance(value, (list, tuple)):
            raise ValidationError(errormsg)
        code = None
        val = None
        for v in value:
            if v.startswith('captcha.'):
                code = v[8:]
            else:
                val = ''.join(v.split()).lower()
        k = des(settings.SECRET_KEY[-8:])
        result = loads(k.decrypt(b64decode(code, altchars='._'), pad='='))
        if result[0].lower() != val:
            raise ValidationError(errormsg)
        return True

def render_image(request, code):
    k = des(settings.SECRET_KEY[-8:])
    result = loads(k.decrypt(b64decode(code, altchars='._'), pad='='))
    options = {}
    for idx, f in enumerate(DYNFIELDS):
        options[f] = result[idx]
    f = DynCaptchaWidget(options=options)
    img = Image.new('RGB', f.csettings['imagesize'], f.csettings['bgcolor'])
    t = options['timestamp']
    tt = t.time()
    seednum = t.day*86400 + tt.hour*1440 + tt.minute*60 + tt.second
    img = f.generate_image(img, seednum)
    response = HttpResponse(mimetype='image/gif')
    img.save(response, format='gif')
    return response
